<?php
/**
 * Created by jinqiang on 2024/7/18 15:31.
 * Copyright (c) 2024, Your Company. All rights reserved.
 */


namespace App\Http\Services\Produce;


use App\Http\Models\Mysql\SsyProcessingAbandonedTable;
use App\Http\Models\Mysql\SsyProcessingFactoryNameTable;
use App\Http\Models\Mysql\SsyProcessingListDetailsQcLogTable;
use App\Http\Models\Mysql\SsyProcessingListDetailsQtLogTable;
use App\Http\Models\Mysql\SsyProcessingListDetailsTable;
use App\Http\Models\Mysql\SsyProcessingListShenqingTable;
use App\Http\Models\Mysql\SsyProcessingListTable;
use App\Http\Repository\RfidRepository;
use Illuminate\Support\Facades\DB;

class RfidService
{
    public function search($param)
    {

        $conn = (new SsyProcessingListDetailsTable())->select(["id","number","s_number","status"])->where('processing_code', $param['processing_code'])
            ->where('sku_code', $param['sku_code']);
        if(isset($param['status']) && $param['status'] != ""){
            $status = (Int)$param['status'];
            $conn = $status == 23 ? $conn->whereIn('status', [2, 3]) : $conn->where('status', $status);
        }
        if($param['number'] ?? ""){
            $conn = $conn->where('number', $param['number']);
        }
        $res = $conn->paginate((Int)$param['limit'])->toArray();
        return [
            'data' => $res['data'],
            'total' => $res['total']
        ];
    }

    public function searchAdd($param)
    {
        $conn = new SsyProcessingListShenqingTable();
        if($param['processing_code'] ?? ""){
            $conn = $conn->where('processing_code', 'like', $param['processing_code']."%");
        }
        if($param['sku_code'] ?? ""){
            $conn = $conn->where('sku_code', 'like', $param['sku_code']."%");
        }
        $res = $conn->orderBy('createtime', 'desc')->paginate((Int)$param['limit'])->toArray();
        return [
            'data' => $res['data'],
            'total' => $res['total']
        ];
    }

    public function searchCancel($param)
    {
        $conn = (new SsyProcessingAbandonedTable())->where('status', (Int)$param['status']);
        if($param['processing_code'] ?? ""){
            $conn = $conn->where('processing_code', 'like', $param['processing_code']."%");
        }
        if($param['sku_code'] ?? ""){
            $conn = $conn->where('sku_code', 'like', $param['sku_code']."%");
        }
        if($param['confirmtime'] ?? []){
            $start = $param['confirmtime'][0]." 00:00:00";
            $end = $param['confirmtime'][1]." 23:59:59";
            $conn = $conn->whereBetween('confirmtime', [$start, $end]);
        }
        $res = $conn->orderBy("createtime", "desc")->paginate((Int)$param['limit'])->toArray();
        return [
            'data' => $res['data'],
            'total' => $res['total']
        ];
    }

    public function searchPrint($param)
    {
        $field = ["id","type_name","type_no","color_code","size_code","sku_code","processing_code","num","bunum","factory_name","overflow",
            "lou_num","createtime","source_type"];
        $conn = (new SsyProcessingListTable())->select($field);
        if($param['processing_code'] ?? ""){
            if(preg_match("/^[a-zA-Z]/is", $param['processing_code'])) {
                $conn = $conn->where('processing_code', 'like', $param['processing_code'] . "%");
            }else{
                $conn = $conn->where('processing_code', 'like', "%". $param['processing_code'] . "%");
            }
        }
        if($param['sku_code'] ?? ""){
            if(preg_match("/^[a-zA-Z]/is", $param['sku_code'])) {
                $conn = $conn->where('sku_code', 'like', $param['sku_code'] . "%");
            }else{
                $conn = $conn->where('sku_code', 'like', "%". $param['sku_code'] . "%");
            }
        }
        if($param['number'] ?? ""){
            $detailObj = (new SsyProcessingListDetailsTable())->where("number", $param['number'])->first();
            if($detailObj->processing_code ?? ""){
                $conn = $conn->where('processing_code', $detailObj->processing_code)->where('sku_code', $detailObj->sku_code);
            }else{
                return ['data' => [], 'total' => 0];
            }
        }
        if($param['brand_code'] ?? ""){
            $conn = $conn->where("brand_code", $param['brand_code']);
        }
        $res = $conn->orderBy("createtime", "desc")->paginate((Int)$param['limit'])->toArray();
        foreach($res['data'] as &$item){
            //已打印
            $item['dayin_num'] = (new SsyProcessingListDetailsTable())->where('processing_code', $item['processing_code'])->where('sku_code', $item['sku_code'])
                ->whereIn('status', [1, 2, 3, 4, 5])->count();
            $usedNum = (new SsyProcessingListDetailsTable())->where('processing_code', $item['processing_code'])->where('sku_code', $item['sku_code'])
                ->whereIn('status', [0, 1, 2, 3, 4, 5])->count();// 包括:0未打印 1已打印 2QC合格 3仓检合格 4入库 5出库（排除：11作废，15销退）
            if(!empty($item['overflow'])){//溢出比
                $kebuNum= $item['num']+$item['lou_num']+ceil($item['num']*$item['overflow'])-$usedNum;
                $item['yichu_num']= ceil($item['num']*$item['overflow']);
                $item['kebu_num'] = $kebuNum >= 0 ? $kebuNum : 0;
            }else{
                $overflow = config("scm.overflow");
                $kebuNum = $item['num']+$item['lou_num']+ceil($item['num'] * $overflow)-$usedNum;
                $item['kebu_num'] = $kebuNum >= 0 ? $kebuNum : 0;
                $item['yichu_num'] = ceil($item['num'] * $overflow);
                $item['overflow'] = $overflow;
            }
        }
        unset($item);
        return [
            'data' => $res['data'],
            'total' => $res['total']
        ];
    }

    public function getNumber($number)
    {
        $resp = (new SsyProcessingListDetailsTable())->where('number', $number)->first();
        if(empty($resp)){
            return [];
        }
        $res = $resp->toArray();
        $qcList = (new SsyProcessingListDetailsQcLogTable())->where('number', $number)->get(['qc_user', 'status', 'qc_time', 'reason_title'])->toArray();
        $qtList = (new SsyProcessingListDetailsQtLogTable())->where('number', $number)->get(['qc_user as qt_user', 'status', 'qc_time', 'reason_title'])->toArray();
        $list = array_merge($qcList, $qtList);
        if(!empty($list)){
            $qcTimes = array_column($list, 'qc_time');
            $timestamps = array_map(function($time) {
                return strtotime($time);
            }, $qcTimes);
            array_multisort($timestamps, SORT_ASC, $list);
        }
        $res['list'] = $list;
        return $res;
    }

    public function chancelCheck($id, $status)
    {
        $abandonedObj = (new SsyProcessingAbandonedTable())->where('id', $id)->first()->toArray();
        DB::beginTransaction();
        $confirmTime = date('Y-m-d H:i:s');
        $res = (new SsyProcessingAbandonedTable())->updateData($id, ['status' => $status, 'confirmtime' => $confirmTime]);
        if($res['code'] !== 0){
            DB::rollBack();
            return $res;
        }
        if($status == 1){
            $whereParam = [
                'processing_code' => $abandonedObj['processing_code'],
                'sku_code' => $abandonedObj['sku_code'],
                's_number' => ['between' => [$abandonedObj['str_s_number'], $abandonedObj['end_s_number']]],
            ];
            $detailRes = (new SsyProcessingListDetailsTable())->updateDataWhere($whereParam, ['status' => 11, 'zuo_time' => $confirmTime]);
            if($detailRes['code'] !== 0){
                DB::rollBack();
                return $detailRes;
            }
        }
        DB::commit();
        return $res;
    }

    public function count($processingCode, $skuCode)
    {
        //未打印
        $unPrintNum = (new SsyProcessingListDetailsTable())->where('processing_code', $processingCode)->where('sku_code', $skuCode)->where('status', 0)->count();
        //已打印
        $printNum = (new SsyProcessingListDetailsTable())->where('processing_code', $processingCode)->where('sku_code', $skuCode)->where('status', 1)->count();
        //待入库
        $unWmsNum = (new SsyProcessingListDetailsTable())->where('processing_code', $processingCode)->where('sku_code', $skuCode)->whereIn('status', [2,3])->count();
        //已入库
        $wmsNum = (new SsyProcessingListDetailsTable())->where('processing_code', $processingCode)->where('sku_code', $skuCode)->where('status', 4)->count();
        //作废
        $invalidNum = (new SsyProcessingListDetailsTable())->where('processing_code', $processingCode)->where('sku_code', $skuCode)->where('status', 11)->count();
        return [
            'unPrintNum' => $unPrintNum,
            'printNum' => $printNum,
            'unWmsNum' => $unWmsNum,
            'wmsNum' => $wmsNum,
            'invalidNum' => $invalidNum
        ];
    }

    public function add($processingCode, $skuCode, $num)
    {
        $processingObj = (new SsyProcessingListTable())->where('processing_code', $processingCode)->where('sku_code',$skuCode)->first()->toArray();
        $yichuNum = ceil ($processingObj['num'] * ($processingObj['overflow'] ?: config("scm.overflow")));
        $totalNum = $processingObj['num'] + $yichuNum + $processingObj['lou_num'];
        $validNum = (new SsyProcessingListDetailsTable())->where('processing_code', $processingCode)->where('sku_code',$skuCode)
            ->whereIn('status', [0, 1, 2, 3, 4, 5])->count();
        $maxAddNum = $totalNum - $validNum;
        if($num > $maxAddNum){
            return ['code' => -1, 'msg' => "补码失败：超过最大可申请数({$maxAddNum}件)"];
        }
        DB::beginTransaction();
        $createRfidRes = RfidRepository::createNumber($processingObj['processing_code'], $processingObj['type_no'], $processingObj['sku_code'], $processingObj['type_name'],
            $processingObj['color_code'], $processingObj['size_code'], $num, $processingObj['factory_name'], $processingObj['supplier_id'], false);
        if($createRfidRes['code'] !== 0){
            DB::rollBack();
            return $createRfidRes;
        }
        DB::commit();
        return $createRfidRes;
    }

    public function del($processingCode, $skuCode, $num_1, $num_2)
    {
        $processingObj = (new SsyProcessingListTable())->where('processing_code', $processingCode)->where('sku_code',$skuCode)->first()->toArray();
        $factoryObj = (new SsyProcessingFactoryNameTable())->where('supplier_id', $processingObj['supplier_id'])->first();
        $isFree = $factoryObj->is_free ?? false;//是Qc免检
        //获取当前加工单的流水号，最大，最小值
        $status = $isFree ? [0, 1, 2] : [0, 1];
        $minSNum = (new SsyProcessingListDetailsTable())->where('processing_code', $processingCode)->where('sku_code',$skuCode)->whereIn('status', $status)
            ->min('s_number');
        $maxSNum = (new SsyProcessingListDetailsTable())->where('processing_code', $processingCode)->where('sku_code',$skuCode)->whereIn('status', $status)
            ->max('s_number');
        if($num_1 < $minSNum || $num_1 > $maxSNum || $num_2 < $minSNum || $num_2 > $maxSNum){
            return ['code' => -1, 'msg' => '作废流水号, 不在范围值内'];
        }
        if($num_1 > $num_2){
            return ['code' => -1, 'msg' => '请正确输入流水号'];
        }
        $data = [
            'type_name' => $processingObj['type_name'],
            'type_no' => $processingObj['type_no'],
            'color_code' => $processingObj['color_code'],
            'size_code' => $processingObj['size_code'],
            'sku_code' => $processingObj['sku_code'],
            'processing_code' => $processingObj['processing_code'],
            'str_s_number' => $num_1,
            'end_s_number' => $num_2,
            'num' => $num_2-$num_1+1,
            'applicant' => auth()->guard("api")->user()->name, //申请人
            'createtime' => date('Y-m-d H:i:s')
        ];
        return (new SsyProcessingAbandonedTable())->createData($data);
    }
}
